/**
 * 
 */
package com.jolestar.yayaweibotong.dao;

import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.repackaged.com.google.common.base.Predicate;
import com.google.appengine.repackaged.com.google.common.collect.Iterables;
import com.google.appengine.repackaged.com.google.common.collect.Lists;
import com.jolestar.yayaweibotong.ServiceType;
import com.jolestar.yayaweibotong.service.UserService;

/**
 * @author jolestar@gmail.com
 * 
 */
public class StatusDomain extends AbstractDomain {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1479113680785313995L;
	public static final String CREATED_AT_PROPERTY = "created_at";
	public static final String RETWEET_ID_PROPERTY = "retweet_id";
	public static final String IS_SYNCED_PROPERTY = "is_synced";
	public static final String SYNCED_AT_PROPERTY = "synced_at";
	public static final String ACCOUNT_ID_PROPERTY = "account_id";
	public static final String TEXT_PROPERTY = "text";
	public static final String RETWEET_PROPERTY = "retweet";
	public static final String IS_RETWEET_PROPERTY = "is_retweet";
	public static final String THUMBNAIL_PIC_PROPERTY = "thumbnail_pic";
	public static final String BMIDDLE_PIC_PROPERTY = "bmiddle_pic";
	public static final String ORIGINAL_PIC_PROPERTY = "original_pic";
	public static final String ORIGINAL_PIC_SHORT_URL_PROPERTY = "original_pic_short_url";
	//原始status
	public static final String ORIGINAL_STATUS_PROPERTY = "original_status";
	public static final String IS_ORIGINAL_STATUS_PROPERTY = "is_original_status";
	
	public static final int DEFAULT_STATUS_LENGTH = 200;

	private RetweetDomain retweet;

	/**
	 * 
	 */
	public StatusDomain(ServiceType serviceType, String id,
			AccountDomain account) {
		super(serviceType, id);
		this.set(ACCOUNT_ID_PROPERTY, account.getOriginalId());
		this.set(IS_RETWEET_PROPERTY, false);
		this.set(IS_SYNCED_PROPERTY, false);
		this.set(IS_ORIGINAL_STATUS_PROPERTY, true);
	}

	public StatusDomain(Entity entity) {
		super(entity);
		Key ret = this.get(RETWEET_PROPERTY);
		if (ret != null) {
			this.retweet = DomainFactory.load(ret);
		}
	}

	public String getText() {
		return this.get(TEXT_PROPERTY);
	}

	public void setText(String text) {
		this.set(TEXT_PROPERTY, text);
	}

	public Date getCreateAt() {
		return this.get(CREATED_AT_PROPERTY);
	}

	public void setCreateAt(Date date) {
		this.set(CREATED_AT_PROPERTY, date);
	}

	public boolean isRetweet() {
		return this.get(IS_RETWEET_PROPERTY, false);
	}

	public void setRetweet(RetweetDomain retweet) {
		this.retweet = retweet;
		this.set(RETWEET_PROPERTY, retweet.getKey());
		this.set(IS_RETWEET_PROPERTY, true);
	}

	public RetweetDomain getRetweet() {
		return this.retweet;
	}

	public boolean isSynced() {
		return this.get(IS_SYNCED_PROPERTY, false);
	}

	public void setSynced(boolean synced) {
		this.set(IS_SYNCED_PROPERTY, synced);
	}

	public void setSyncedAt(Date date) {
		this.set(SYNCED_AT_PROPERTY, date);
	}

	public Date getSyncedAt() {
		return this.get(SYNCED_AT_PROPERTY);
	}

	public String getThumbnailPic() {
		return this.get(THUMBNAIL_PIC_PROPERTY);
	}

	public void setThumbnailPic(String img) {
		this.set(THUMBNAIL_PIC_PROPERTY, img);
	}

	public String getBmiddlePic() {
		return this.get(BMIDDLE_PIC_PROPERTY);
	}

	public void setBmiddlePic(String img) {
		this.set(BMIDDLE_PIC_PROPERTY, img);
	}

	public void setOriginalPic(String img) {
		this.set(ORIGINAL_PIC_PROPERTY, img);
	}

	public String getOriginalPic() {
		return this.get(ORIGINAL_PIC_PROPERTY);
	}

	public void setOriginalPicShortUrl(String url) {
		this.set(ORIGINAL_PIC_SHORT_URL_PROPERTY, url);
	}

	public String getOriginalPicShortUrl() {
		return this.get(ORIGINAL_PIC_SHORT_URL_PROPERTY);
	}

	public AccountDomain getAccount() {
		String originalId = this.get(ACCOUNT_ID_PROPERTY);
		if (originalId == null) {
			return null;
		}
		return UserService.ServiceHolder.getInstance().getAccount(
				this.getServiceType(), originalId);
	}
	
	public String getAcountId(){
		String originalId = this.get(ACCOUNT_ID_PROPERTY);
		return originalId;
	}
	
	public String getFormatText(){
		return this.formatStatus(DEFAULT_STATUS_LENGTH);
	}

	public String formatStatus(int statusLengthLimit) {
		StringBuilder text = new StringBuilder();
		text.append(getText());
		if (this.getOriginalPic() != null) {
			text.append(" "+this.getOriginalPicShortUrl());
		}
		//twitter 的 rt 信息直接在原文中，不用附加retweet信息。
		if (isRetweet() && this.getServiceType() != ServiceType.twitter) {
			text.append(" @" + getRetweet().getUserScreenName());
			text.append(" "+getRetweet().getText());
			if (getRetweet().getOriginalPic() != null) {
				text.append(" "+getRetweet().getOriginalPicShortUrl());
			}
		}
		if (statusLengthLimit < 0 || text.length() <= statusLengthLimit) {
			return text.toString();
		} else {
			if (text.charAt(statusLengthLimit) != ' ') {
				for (int i = statusLengthLimit - 1; i > 0; i--) {
					char c = text.charAt(i);
					if ( c == ' '||c == '，'||c == '。') {
						return text.substring(0, i);
					}
					// 避免截断 ＠用户名
					if (c == '@') {
						return text.substring(0, i);
					}
					// TODO 避免截断link
					if (i > 6 && text.charAt(i) == '/'
							&& text.charAt(i - 1) == '/'
							&& text.charAt(i - 2) == ':'
							&& text.charAt(i - 3) == 'p'
							&& text.charAt(i - 4) == 't'
							&& text.charAt(i - 5) == 't'
							&& text.charAt(i - 6) == 'h') {
						return text.substring(0, i-6);
					}
				}
			}
			return text.substring(0, statusLengthLimit);
		}
	}

	public <T> void addProperty(String name, T value) {
		this.set(name, value);
	}

	public <T> T getProperty(String name) {
		return this.get(name);
	}
	
	public StatusDomain getOriginalStatus(){
		Key key = this.get(ORIGINAL_STATUS_PROPERTY);
		if(key == null){
			return null;
		}
		return DomainFactory.load(key);
	}
	
	public void setOriginalStatus(StatusDomain status){
		this.set(ORIGINAL_STATUS_PROPERTY, status.getKey());
		this.set(IS_ORIGINAL_STATUS_PROPERTY, false);
	}
	
	public boolean isOriginalStatus(){
		return this.get(IS_ORIGINAL_STATUS_PROPERTY, true);
	}

	@Override
	public void save() {
		if (this.retweet != null) {
			this.retweet.save();
		}
		super.save();
	}
	
	public List<AccountDomain> getOtherAccounts(){
		final AccountDomain account = this.getAccount();
		if(account == null){
			return Collections.emptyList();
		}
		List<AccountDomain> accounts = account.getUser().getAllAccounts();
		return Lists.newUnmodifiableArrayList(Iterables.filter(accounts, new Predicate<AccountDomain>(){
			@Override
			public boolean apply(AccountDomain a) {
				if(a.getKeyName().equals(account.getKeyName())){
					return false;
				}
				if(!a.isActivity()){
					return false;
				}
				if(!a.getServiceType().isEnable()){
					return false;
				}
				return true;
			}
			
		}));
	}


}
